class MapGraph {
  Treemap map;
  WordMap mapData;
  String[] lines;
  float tooltipWidth;
  float tooltipHeight;
  int val=1;
  int tooltipCounter=0;
  int treeColor = 125;
  ArrayList[][][] arrayQ;
  int totalMovies;


  MapGraph() {
    tooltipWidth = 130;
    tooltipHeight = 50;
  }

  void setup() {
    //generateMapData();
    arrayQ = new ArrayList[90][13][18];
    for (int i = 0; i < 90; i++) {
      for (int j = 0; j < 13; j++) {
        for (int k = 0; k < 18; k++) {
          arrayQ[i][j][k] = new ArrayList<Integer>();
        }
      }
    }

    ratingsPerYear();
  }

  void printIndicies() {
    for (int i = 0; i < 90; i++) {
      for (int j = 0; j < 13; j++) {
        //println(i + " " + j);  
        if (!arrayQ[i][j][0].isEmpty())
          println(arrayQ[i][j][0].size());
      }
    }
  }

  void draw() {
    tooltipCounter++;
    generateMapData();
    zoomBounds.update();
    map.draw();
    if (rolloverItem != null && tooltipCounter > 4 && mouseInGraphArea()) {
      drawTooltip();
    }
    //printIndicies();
    calculateIndex();
  }

  void ratingsPerYear()
  {
    int theYear = 1920;
    int k = 0;
    String tempStr = "";
    int[][] tempTotals = new int [2010 - 1920][13];
    yearIndex = new int [tempTotals.length][];
    int[] monthIndex;

    for( int i = 0; i < tempTotals.length; i++)
    {
      monthIndex = new int[months.length];
      for( int j = 0; j < monthIndex.length; j++)
      {
        monthIndex[j] = k;
        while( ( k < data.getRowCount() ) && ( months[j].equalsIgnoreCase( data.getData( k, 1) ) ) )
        {

          if (data.getData( k, 3).equals(genres[0])) { 
            arrayQ[i][j][0].add(k);
          }  //action
          else if (data.getData( k, 3).equals(genres[1])) { 
            arrayQ[i][j][1].add(k);
          }  //adventure
          else if (data.getData( k, 3).equals(genres[2])) { 
            arrayQ[i][j][2].add(k);
          }  //animation
          else if (data.getData( k, 3).equals(genres[3])) { 
            arrayQ[i][j][3].add(k);
          }  //comedy
          else if (data.getData( k, 3).equals(genres[4])) { 
            arrayQ[i][j][4].add(k);
          }  //crime
          else if (data.getData( k, 3).equals(genres[5])) { 
            arrayQ[i][j][5].add(k);
          }  //documentary
          else if (data.getData( k, 3).equals(genres[6])) { 
            arrayQ[i][j][6].add(k);
          }  //drama
          else if (data.getData( k, 3).equals(genres[7])) { 
            arrayQ[i][j][7].add(k);
          }  //fantasy
          else if (data.getData( k, 3).equals(genres[8])) { 
            arrayQ[i][j][8].add(k);
          }  //family
          else if (data.getData( k, 3).equals(genres[9])) { 
            arrayQ[i][j][9].add(k);
          }  //film-noir
          else if (data.getData( k, 3).equals(genres[10])) { 
            arrayQ[i][j][10].add(k);
          }  //horror
          else if (data.getData( k, 3).equals(genres[11])) { 
            arrayQ[i][j][11].add(k);
          }  //musical
          else if (data.getData( k, 3).equals(genres[12])) { 
            arrayQ[i][j][12].add(k);
          }  //mysterry
          else if (data.getData( k, 3).equals(genres[13])) { 
            arrayQ[i][j][13].add(k);
          }  //romance
          else if (data.getData( k, 3).equals(genres[14])) { 
            arrayQ[i][j][14].add(k);
          }  //sci-fi
          else if (data.getData( k, 3).equals(genres[15])) { 
            arrayQ[i][j][15].add(k);
          }  //thriller
          else if (data.getData( k, 3).equals(genres[16])) { 
            arrayQ[i][j][16].add(k);
          }  //war
          else if (data.getData( k, 3).equals(genres[17])) { 
            arrayQ[i][j][17].add(k);
          }  //western

          k++;
        }
      }
      yearIndex[i] = monthIndex;
      theYear++;
    }
  }

  void calculateIndex() {
    //genreSelected[];
    //String[] genres = { "Action", "Adventure", "Animation", "Comedy", "Crime", "Documentary", "Drama", "Fantasy", "Family", "Film-Noir", "Horror", "Musical", "Mystery", "Romance", "Sci-Fi", "Thriller", "War", "Western"};
    //ArrayList<int> indexArray = new ArrayList<int>();

    String topVotes[][] = new String[5][2];
    String topRatings[][] = new String[5][2];
    String previousMovie = "";

    for (int i=0; i<5;i++) {
      topVotes[i][0] = "0";
      topVotes[i][1] = "0";
      topRatings[i][0] = "0";
      topRatings[i][1] = "0";
    }

    if( clusterMode == yearsMode)
    {
      int i = rangeYears[0]-1920;
      do {
        for (int j = 0; j < 13; j++) {
          for (int m=0; m<18; m++) {
            if(genreSelected[m]) {
              for (int k=0; k < arrayQ[i][j][m].size(); k++) {
                int tempValue = ((Integer)arrayQ[i][j][m].get(k)).intValue();

                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topVotes[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") && Integer.parseInt(data.getData( tempValue, 4)) > Integer.parseInt(topVotes[l][1])) {
                    topVotes[l][0] = data.getData( tempValue, 0);
                    topVotes[l][1] = data.getData( tempValue, 4);
                    break;
                  }
                }
                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topRatings[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") ) {
                    if (Integer.parseInt(data.getData( tempValue, 4)) < getMinValue(Integer.parseInt(data.getData( tempValue, 2)))) {
                      break;
                    }
                  } 
                  else {
                    break;
                  }
                  if (!data.getData( tempValue, 5).equals("") && Double.parseDouble(data.getData( tempValue, 5)) > Double.parseDouble(topRatings[l][1])) {
                    topRatings[l][0] = data.getData( tempValue, 0);
                    topRatings[l][1] = data.getData( tempValue, 5);
                    break;
                  }
                }
              }
            }
          }
          
        } 
        i++;
      }while (i < rangeYears[1]-1920);
    }
    else if( clusterMode == monthsMode )
    {
      int i = rangeYears[0]-1920;
      do {
        for (int j = 0; j < 13; j++) {
          for (int m=0; m<18; m++) {
            if(genreSelected[m]) {
              for (int k=0; k < arrayQ[i][j][m].size(); k++) {
                int tempValue = ((Integer)arrayQ[i][j][m].get(k)).intValue();

                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topVotes[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") && Integer.parseInt(data.getData( tempValue, 4)) > Integer.parseInt(topVotes[l][1])) {
                    topVotes[l][0] = data.getData( tempValue, 0);
                    topVotes[l][1] = data.getData( tempValue, 4);
                    break;
                  }
                }
                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topRatings[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") ) {
                    if (Integer.parseInt(data.getData( tempValue, 4)) < getMinValue(Integer.parseInt(data.getData( tempValue, 2)))) {
                      break;
                    }
                  } 
                  else {
                    break;
                  }
                  if (!data.getData( tempValue, 5).equals("") && Double.parseDouble(data.getData( tempValue, 5)) > Double.parseDouble(topRatings[l][1])) {
                    topRatings[l][0] = data.getData( tempValue, 0);
                    topRatings[l][1] = data.getData( tempValue, 5);
                    break;
                  }
                }
              }
            }
          }
        }
        i++;
      }while (i < rangeYears[1]-1920);
    }
    else if( clusterMode == seasonsMode )
    {
      int i = rangeYears[0]-1920;
      do {
        for (int j = 0; j < 13; j++) {
          for (int m=0; m<18; m++) {
            if(genreSelected[m]) {
              for (int k=0; k < arrayQ[i][j][m].size(); k++) {
                int tempValue = ((Integer)arrayQ[i][j][m].get(k)).intValue();

                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topVotes[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") && Integer.parseInt(data.getData( tempValue, 4)) > Integer.parseInt(topVotes[l][1])) {
                    topVotes[l][0] = data.getData( tempValue, 0);
                    topVotes[l][1] = data.getData( tempValue, 4);
                    break;
                  }
                }
                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topRatings[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") ) {
                    if (Integer.parseInt(data.getData( tempValue, 4)) < getMinValue(Integer.parseInt(data.getData( tempValue, 2)))) {
                      break;
                    }
                  } 
                  else {
                    break;
                  }
                  if (!data.getData( tempValue, 5).equals("") && Double.parseDouble(data.getData( tempValue, 5)) > Double.parseDouble(topRatings[l][1])) {
                    topRatings[l][0] = data.getData( tempValue, 0);
                    topRatings[l][1] = data.getData( tempValue, 5);
                    break;
                  }
                }
              }
            }
          }
        }
        i++;
      }while (i < rangeYears[1]-1920);
    }
    else  // decades
    {
      int i = rangeYears[0]-1920;
      do {
        for (int j = 0; j < 13; j++) {
          for (int m=0; m<18; m++) {
            if(genreSelected[m]) {
              for (int k=0; k < arrayQ[i][j][m].size(); k++) {
                int tempValue = ((Integer)arrayQ[i][j][m].get(k)).intValue();

                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topVotes[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") && Integer.parseInt(data.getData( tempValue, 4)) > Integer.parseInt(topVotes[l][1])) {
                    topVotes[l][0] = data.getData( tempValue, 0);
                    topVotes[l][1] = data.getData( tempValue, 4);
                    break;
                  }
                }
                for (int l=0; l<5;l++) {
                  if (data.getData( tempValue, 0).equals(topRatings[l][0])) { 
                    break;
                  }
                  if (!data.getData( tempValue, 4).equals("") ) {
                    if (Integer.parseInt(data.getData( tempValue, 4)) < getMinValue(Integer.parseInt(data.getData( tempValue, 2)))) {
                      break;
                    }
                  } 
                  else {
                    break;
                  }
                  if (!data.getData( tempValue, 5).equals("") && Double.parseDouble(data.getData( tempValue, 5)) > Double.parseDouble(topRatings[l][1])) {
                    topRatings[l][0] = data.getData( tempValue, 0);
                    topRatings[l][1] = data.getData( tempValue, 5);
                    break;
                  }
                }
              }
            }
          }
        }
        i++;
      }while (i < rangeYears[1]-1920);
    }
    int tempY=30;
    fill(255);
    textAlign(CENTER);
    textSize(9);
    for (int i=0; i<5;i++) {
      //println(topVotes[i][0]);
      //println(topRatings[i][0]);
      if (topRatings[i][0].length() <=35) {
        text(topRatings[i][0], width-125, tempY);
      }
      else {
        text(topRatings[i][0].substring(0,35) + "...", width-125, tempY);
      }

      if (topVotes[i][0].length() <=35) {
        text(topVotes[i][0], width-375, tempY);
      }
      else {
        text(topVotes[i][0].substring(0,35) + "...", width-375, tempY);
      }
      tempY+=15;
    }
  }

  int getMinValue(int x) {
    if (x >= 1920 && x < 1930) {
      return 45;
    }
    else if(x >= 1930 && x < 1940) {
      return 130;
    }
    else if(x >= 1940 && x < 1950) {
      return 300;
    }
    else if(x >= 1950 && x < 1960) {
      return 400;
    }
    else if(x >= 1960 && x < 1970) {
      return 400;
    }
    else if(x >= 1970 && x < 1980) {
      return 400;
    }
    else if(x >= 1980 && x < 1990) {
      return 1000;
    }
    else if(x >= 1990 && x < 2000) {
      return 2000;
    }
    return 3000;
  }

  boolean mouseInGraphArea() {
    if (mouseX > mapGraphCornerX && mouseX < mapGraphCornerX+mapWidth && mouseY > mapGraphCornerY && mouseY < mapGraphCornerY+mapHeight)
    {
      return true;
    }
    return false;
  }

  void generateMapData() {
    mapData = new WordMap();
    for( int i = yearIndex[rangeYears[0]-1920][0] ; i < yearIndex[(rangeYears[1]-1920)][12]; i++)
    {
      mapData.addWord(data.getData(i,3));
    }
    mapData.finishAdd();
    map = new Treemap(mapData, mapGraphCornerX, mapGraphCornerY, mapWidth, mapHeight);
    zoomBounds = new BoundsIntegrator(mapGraphCornerX, mapGraphCornerY, mapWidth, mapHeight);
  }

  void drawTooltip() {
    fill(#F57900, 200);
    strokeWeight(0);
    rect(mouseX+15, mouseY+15, tooltipWidth, tooltipHeight);    
    fill(0);
    text("Genre: " + rolloverItem.getWord() + "\nFilms: " + int((float)rolloverItem.getSize()),mouseX+tooltipWidth/2+15, mouseY+tooltipHeight/2+15);
  }

  void keyReleased()
  {

    if(key == 'q' || key == 'Q')
    {

      if (val==1) {
        val = 2;
      } 
      else if (val==2) {
        val = 1;
      }
      mapData = new WordMap();
      for (int i = 0; i < data.getRowCount()/val; i++)
      {
        mapData.addWord(data.getData(i,3));
      }
      mapData.finishAdd();
      map = new Treemap(mapData, mapGraphCornerX, mapGraphCornerY, mapWidth, mapHeight);
      zoomBounds = new BoundsIntegrator(mapGraphCornerX, mapGraphCornerY, mapWidth, mapHeight);
    }
  }

  void mouseMoved() {
    tooltipCounter = 0;
  }
}

//      for(int i = 0; i<data.getRowCount();  i++)////----IMPORTANT : This is the place where you load the array of rows of the genre column to be counted and presented----//////
//        {                                          //////---IN THE FUTURE WE NEED TO MODIFY THIS to change with sliders and clusters 
//          lines[i] = data.getData(i,3);
//        }


// different choices for the layout method
//MapLayout algorithm = new SliceLayout();
//MapLayout algorithm = 
//MapLayout algorithm = new StripTreemap();
//MapLayout algorithm = new SquarifiedLayout();

